package com.jboltai.resource.functioncall;

import cn.hutool.core.util.StrUtil;
import com.jboltai.config.JBoltAIConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class FunctionResourceCenter {

    private static final Logger LOGGER = LoggerFactory.getLogger(JBoltAIConfig.LOGGER_NAME);
    /**
     * function 资源
     */
    private static final ConcurrentHashMap<String, FunctionResource> FUNCTION_RESOURCES = new ConcurrentHashMap<>();

    /**
     * function 分组
     */
    private static final ConcurrentHashMap<String, CopyOnWriteArrayList<String>> FUNCTION_GROUP = new ConcurrentHashMap<>();


    /**
     * 注册 function 资源
     * @param functionResource
     * @return
     */
    public static FunctionResource register(FunctionResource functionResource) {
        FunctionResource prev = FUNCTION_RESOURCES.putIfAbsent(functionResource.getId(), functionResource);
        if (prev != null && prev != functionResource) {
            throw new RuntimeException("已注册id为[" + functionResource.getId() + "]的Function资源，不可重复注册");
        }
        return functionResource;
    }

    /**
     * 注册 function 资源，如果已存在同id的跳过
     * @param functionResource
     * @return
     */
    public static void registerIfNotExist(FunctionResource functionResource) {
        FUNCTION_RESOURCES.putIfAbsent(functionResource.getId(), functionResource);
    }

    /**
     * 注册 function 资源
     * @param groupId 分组id
     * @param functionResources
     * @return
     */
    public static FunctionResource[] register(String groupId, FunctionResource[] functionResources) {
        if(functionResources != null){
            for(FunctionResource functionResource:functionResources){
                register(groupId,functionResource);
            }
        }
        return functionResources;
    }

    /**
     * 注册 function 资源
     * @param groupId 分组id
     * @param functionResource
     * @return
     */
    public static FunctionResource register(String groupId, FunctionResource functionResource) {
        register(functionResource);
        CopyOnWriteArrayList<String> resourceIds = FUNCTION_GROUP.computeIfAbsent(groupId, k -> new CopyOnWriteArrayList<String>());
        boolean exist = resourceIds.addIfAbsent(functionResource.getId());
        if (!exist) {
            throw new RuntimeException("FunctionGroup["+groupId+"]中已存在id为[" + functionResource.getId() + "]的Function资源，不可重复注册");
        }
        return functionResource;
    }
    /**
     * 注册 function 资源
     * @param groupId 分组id
     * @param functionResource
     * @return
     */
    public static void registerIfNotExist(String groupId, FunctionResource functionResource) {
        registerIfNotExist(functionResource);
        CopyOnWriteArrayList<String> resourceIds = FUNCTION_GROUP.computeIfAbsent(groupId, k -> new CopyOnWriteArrayList<String>());
        resourceIds.addIfAbsent(functionResource.getId());
    }


    /**
     * 取消注册指定id的资源
     * @param functionIds
     */
    public static void unregister(String... functionIds) {
        if(functionIds != null){
            for(String functionId:functionIds){
                FUNCTION_RESOURCES.remove(functionId);
                for (CopyOnWriteArrayList<String> strings : FUNCTION_GROUP.values()) {
                    strings.removeIf(s -> s.equals(functionId));
                }
            }
        }
    }

    /**
     * 更新FunctionResource定义
     * @param functionResource
     */
    public static void update(FunctionResource functionResource) {
        if(functionResource == null){
            throw new RuntimeException("FunctionResource更新资源不能为空");
        }
        if(StrUtil.isBlank(functionResource.getId())){
            throw new RuntimeException("FunctionResource["+functionResource.getName()+":"+functionResource.getDescription()+"]未定义id");
        }
        FunctionResource prev = FUNCTION_RESOURCES.remove(functionResource.getId());
        if (prev == null) {
            throw new RuntimeException("id为[" + functionResource.getId() + "]的Function资源未注册，不可更新");
        }
        register(functionResource);
    }

    /**
     * 更新FunctionResource定义
     * 判断存在的资源才去执行更新
     * @param functionResource
     */
    public static void updateIfExist(FunctionResource functionResource) {
        if(functionResource == null){
            throw new RuntimeException("FunctionResource更新资源不能为空");
        }
        if(StrUtil.isBlank(functionResource.getId())){
            throw new RuntimeException("FunctionResource["+functionResource.getName()+":"+functionResource.getDescription()+"]未定义id");
        }
        if(checkExist(functionResource.getId())){
            FunctionResource prev = FUNCTION_RESOURCES.remove(functionResource.getId());
            if (prev == null) {
                throw new RuntimeException("id为[" + functionResource.getId() + "]的Function资源未注册，不可更新");
            }
            register(functionResource);
        }
    }



    /**
     * 从某组将某个资源移除
     * @param groupId
     * @param functionIds
     */
    public static void removeFromGroup(String groupId, String... functionIds) {
        CopyOnWriteArrayList<String> group = FUNCTION_GROUP.get(groupId);
        if (group != null && functionIds != null) {
            for (String functionId : functionIds) {
                group.removeIf(s -> s.equals(functionId));
            }
        }
    }


    /**
     * 获取某个组的所有的function 资源id
     * @param groupId
     * @return
     */
    public static List<String> getResourceIdsByGroup(String groupId) {
        return FUNCTION_GROUP.get(groupId);
    }

    /**
     * 检测function 组是否存在
     * @param groupId
     * @return
     */
    public static boolean checkGroupExist(String groupId) {
        return FUNCTION_GROUP.containsKey(groupId);
    }

    /**
     * 取消组
     * @param groupIds
     */
    public static void unregisterGroup(String... groupIds) {
        if (groupIds != null) {
            for (String groupId : groupIds) {
                FUNCTION_GROUP.remove(groupId);
            }
        }

    }


    /**
     * 根据id获取资源
     * @param id
     * @return
     */
    public static FunctionResource getById(String id) {
        return FUNCTION_RESOURCES.get(id);
    }
    /**
     * 根据id获取资源
     * @param id
     * @return
     */
    public static boolean checkExist(String id) {
        return FUNCTION_RESOURCES.containsKey(id);
    }





}
